package com.cskaoyan.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cskaoyan.mall.product.cache.RedisCache;
import com.cskaoyan.mall.product.converter.dto.CategoryConverter;
import com.cskaoyan.mall.product.converter.dto.PlatformAttributeInfoConverter;
import com.cskaoyan.mall.product.converter.dto.TrademarkConverter;
import com.cskaoyan.mall.product.dto.*;
import com.cskaoyan.mall.product.mapper.*;
import com.cskaoyan.mall.product.model.*;
import com.cskaoyan.mall.product.query.CategoryTrademarkParam;
import com.cskaoyan.mall.product.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author Pudding
 * @Date 2024/6/29 15:17
 */
@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    FirstLevelCategoryMapper firstLevelCategoryMapper;
    @Autowired
    SecondLevelCategoryMapper secondLevelCategoryMapper;
    @Autowired
    ThirdLevelCategoryMapper thirdLevelCategoryMapper;
    @Autowired
    CategoryConverter categoryConverter;
    @Autowired
    CategoryTrademarkMapper categoryTrademarkMapper;
    @Autowired
    TrademarkMapper trademarkMapper;
    @Autowired
    TrademarkConverter trademarkConverter;

    //1. 查询所有的一级类目
    @Override
    public List<FirstLevelCategoryDTO> getFirstLevelCategory() {

        //1.1 查询所有的信息
        List<FirstLevelCategory> firstLevelCategories = firstLevelCategoryMapper.selectList(null);

        //1.2 PO对象转换为DTO对象
        List<FirstLevelCategoryDTO> firstLevelCategoryDTOS = categoryConverter.firstLevelCategoryPOs2DTOs(firstLevelCategories);

        return firstLevelCategoryDTOS;
    }

    //2. 根据一级类目id查询所有的二级类目
    @Override
    public List<SecondLevelCategoryDTO> getSecondLevelCategory(Long firstLevelCategoryId) {

        //2.1 构建查询条件
        LambdaQueryWrapper<SecondLevelCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SecondLevelCategory::getFirstLevelCategoryId, firstLevelCategoryId);

        //2.2 进行查询
        List<SecondLevelCategory> secondLevelCategories = secondLevelCategoryMapper.selectList(queryWrapper);

        //2.3 将PO对象转换为DTO对象
        List<SecondLevelCategoryDTO> secondLevelCategoryDTOS = categoryConverter.secondLevelCategoryPOs2DTOs(secondLevelCategories);

        return secondLevelCategoryDTOS;
    }

    //3. 根据二级分类Id 查询三级分类数据
    @Override
    public List<ThirdLevelCategoryDTO> getThirdLevelCategory(Long secondLevelCategoryId) {

        //3.1 构建查询条件
        LambdaQueryWrapper<ThirdLevelCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ThirdLevelCategory::getSecondLevelCategoryId, secondLevelCategoryId);

        //3.2 进行查询
        List<ThirdLevelCategory> thirdLevelCategories = thirdLevelCategoryMapper.selectList(queryWrapper);

        //3.3 将PO对象转换为DTO对象
        List<ThirdLevelCategoryDTO> thirdLevelCategoryDTOS = categoryConverter.thirdLevelCategoryPOs2DTOs(thirdLevelCategories);

        return thirdLevelCategoryDTOS;
    }

    //4. 保存分类与品牌关联，对category_trademark关系表的单表插入
    @Override
    public void save(CategoryTrademarkParam categoryTrademarkParam) {

        //4.1 进行遍历品牌id的List
        for (Long trademarkId : categoryTrademarkParam.getTrademarkIdList()) {
            //4.2 构建插入对象
            CategoryTrademark categoryTrademark = new CategoryTrademark();
            categoryTrademark.setThirdLevelCategoryId(categoryTrademarkParam.getCategory3Id());
            categoryTrademark.setTrademarkId(trademarkId);

            //4.3 插入操作
            categoryTrademarkMapper.insert(categoryTrademark);
        }
    }

    //5. 根据三级分类id查询关联的品牌
    @Override
    public List<TrademarkDTO> findTrademarkList(Long category3Id) {

        //5.1 先根据三级类目id，在类目品牌关联表category_trademark中，找到属于该类目的所有品牌的id即trademark_id
        //5.1.1 构建查询条件
        LambdaQueryWrapper<CategoryTrademark> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CategoryTrademark::getThirdLevelCategoryId, category3Id)
                .select(CategoryTrademark::getTrademarkId);
        List<CategoryTrademark> categoryTrademarkList = categoryTrademarkMapper.selectList(lambdaQueryWrapper);
        //5.1.2 通过流将List<CategoryTrademark>转换为List<trademarkId>
        List<Long> trademarkId = categoryTrademarkList.stream().
                map(CategoryTrademark::getTrademarkId)
                .collect(Collectors.toList());
        //5.2 在根据trademark_id集合，在trademark表中查询出每个品牌的详细信息
        List<Trademark> trademarkList = null;
        if (!trademarkId.isEmpty()) {
            LambdaQueryWrapper<Trademark> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Trademark::getId, trademarkId);
            trademarkList = trademarkMapper.selectList(queryWrapper);
        }

        //5.3 将PO对象转换为DTO对象
        List<TrademarkDTO> trademarkDTOS = trademarkConverter.trademarkPOs2DTOs(trademarkList);
        return trademarkDTOS;
    }


    //6. 获取当前未被三级分类关联的所有品牌
    @Override
    public List<TrademarkDTO> findUnLinkedTrademarkList(Long thirdLevelCategoryId) {

        //6.1 首先查询出当前类目已经关联的品牌列表(在trademark_category中)
        //5.1.1 构建查询条件
        LambdaQueryWrapper<CategoryTrademark> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CategoryTrademark::getThirdLevelCategoryId, thirdLevelCategoryId)
                .select(CategoryTrademark::getTrademarkId);
        List<CategoryTrademark> categoryTrademarkList = categoryTrademarkMapper.selectList(lambdaQueryWrapper);
        //5.1.2 通过流将List<CategoryTrademark>转换为List<trademarkId>
        List<Long> trademarkId = categoryTrademarkList.stream().
                map(CategoryTrademark::getTrademarkId)
                .collect(Collectors.toList());
        //6.2 查询所有品牌的品牌列表，过滤掉已经关联到当前类目的品牌即可
        List<Trademark> trademarkList = null;
        if (!trademarkId.isEmpty()) {
            LambdaQueryWrapper<Trademark> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.notIn(Trademark::getId, trademarkId);
            trademarkList = trademarkMapper.selectList(queryWrapper);
        }

        //6.3 将PO对象转换为DTO对象
        List<TrademarkDTO> trademarkDTOS = trademarkConverter.trademarkPOs2DTOs(trademarkList);
        return trademarkDTOS;
    }

    //7. 删除关联关系
    @Override
    public void remove(Long thirdLevelCategoryId, Long trademarkId) {

        //根据Map条件删除
        HashMap<String, Object> map = new HashMap<>();
        map.put("third_level_category_id", thirdLevelCategoryId);
        map.put("trademark_id", trademarkId);
        categoryTrademarkMapper.deleteByMap(map);
    }

    //8. 获取和该三级类目相关完整信息(包括它所属的一级类目和二级类目）
    @Override
    @RedisCache(prefix = "categoryHierarchyByCategory3Id:")
    public CategoryHierarchyDTO getCategoryViewByCategoryId(Long thirdLevelCategoryId) {

        //8.1 构建需要封装的对象CategoryHierarchyDTO
        CategoryHierarchyDTO categoryHierarchyDTO = new CategoryHierarchyDTO();
        //8.2 查询三级类目
        ThirdLevelCategory thirdLevelCategory = thirdLevelCategoryMapper.selectById(thirdLevelCategoryId);
        //8.3 查询二级类目
        SecondLevelCategory secondLevelCategory = secondLevelCategoryMapper.selectById(thirdLevelCategory.getSecondLevelCategoryId());
        //8.4 查询一级类目
        FirstLevelCategory firstLevelCategory = firstLevelCategoryMapper.selectById(secondLevelCategory.getFirstLevelCategoryId());
        //8.5 封装数据到对象categoryHierarchyDTO
        categoryHierarchyDTO.setFirstLevelCategoryId(firstLevelCategory.getId());
        categoryHierarchyDTO.setFirstLevelCategoryName(firstLevelCategory.getName());
        categoryHierarchyDTO.setSecondLevelCategoryId(secondLevelCategory.getId());
        categoryHierarchyDTO.setSecondLevelCategoryName(secondLevelCategory.getName());
        categoryHierarchyDTO.setThirdLevelCategoryId(thirdLevelCategory.getId());
        categoryHierarchyDTO.setThirdLevelCategoryName(thirdLevelCategory.getName());

        return categoryHierarchyDTO;
    }

    //9. 获取完整的三级类目信息
    @Override
    @RedisCache(prefix = "categoryTreeList:")
    public List<FirstLevelCategoryNodeDTO> getCategoryTreeList() {

        //9.1 获取一级类目列表
        List<FirstLevelCategoryDTO> firstLevelCategory = this.getFirstLevelCategory();
        List<FirstLevelCategoryNodeDTO> firstLevelCategoryNodeDTOS = categoryConverter.firstLevelCategoryPOs2NodeDTOs(firstLevelCategory);

        firstLevelCategoryNodeDTOS.stream().forEach(firstLevelCategoryNodeDTO -> {
            //9.2 根据一级类目id，获取二级类目列表
            List<SecondLevelCategoryDTO> secondLevelCategory = this.getSecondLevelCategory(firstLevelCategoryNodeDTO.getCategoryId());
            List<SecondLevelCategoryNodeDTO> secondLevelCategoryNodeDTOS = categoryConverter.secondLevelCategoryPOs2NodeDTOs(secondLevelCategory);

            secondLevelCategoryNodeDTOS.stream().forEach(secondLevelCategoryNodeDTO -> {
                //9.3 根据二级类目id，获取三级类目列表
                List<ThirdLevelCategoryDTO> thirdLevelCategory = this.getThirdLevelCategory(secondLevelCategoryNodeDTO.getCategoryId());
                List<ThirdLevelCategoryNodeDTO> thirdLevelCategoryNodeDTOS = categoryConverter.thirdLevelCategoryPOs2NodeDTOs(thirdLevelCategory);

                //9.4 封装child到二级类目对象中
                secondLevelCategoryNodeDTO.setCategoryChild(thirdLevelCategoryNodeDTOS);
            });

            //9.5 封装child到一级类目对象中
            firstLevelCategoryNodeDTO.setCategoryChild(secondLevelCategoryNodeDTOS);
        });

        return firstLevelCategoryNodeDTOS;
    }
}
